package com.googlecode.chelonia;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;

public class SessionContainer<T> extends TimerTask {
	private Map<String, Ct<T>> sessions = Collections.synchronizedMap(new HashMap<String, Ct<T>>());
	private Random random = new Random();

	private int maxConnections;
	private int timeout; // five seconds timeout

	private Timer timer = new Timer(true);
	
	public SessionContainer(int timeout){
		this.timeout = timeout;
		this.maxConnections = 1000;
		timer.schedule(this, 1000, 500);
	}

	public SessionContainer() {
		this(5000);
	}

	public String create(T instance) {
		if (sessions.size() < maxConnections) {
			String key = "ik" + random.nextLong();
			Ct<T> ct = new Ct<T>();
			ct.created = System.currentTimeMillis();
			ct.lastAccessed = System.currentTimeMillis();
			ct.subject = instance;
			sessions.put(key, ct);
			return key;
		}
		return null;
	}

	public T get(String key) {
		Ct<T> ct = sessions.get(key);
		if (ct == null) {
			return null;
		}
		ct.lastAccessed = System.currentTimeMillis();
		return ct.subject;
	}

	public class Ct<X> {
		long lastAccessed;
		long created;
		X subject;
	}

	public void remove(String key) {
		sessions.remove(key);
	}

	@Override
	public void run() {
		try {
			Set<String> ns = new HashSet<String>();
			ns.addAll(sessions.keySet());
			for (String key : ns) {
				Ct<T> ct = sessions.get(key);
				if (ct != null) {
					long delta = System.currentTimeMillis() - ct.lastAccessed;
					if (delta > timeout) {
						sessions.remove(key);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
